package pers.lonestar.framework.utils.support.utils;

import java.lang.reflect.Field;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import pers.lonestar.framework.utils.support.converters.BooleanConverter;
import pers.lonestar.framework.utils.support.converters.ByteConverter;
import pers.lonestar.framework.utils.support.converters.CalendarConverter;
import pers.lonestar.framework.utils.support.converters.Converter;
import pers.lonestar.framework.utils.support.converters.DateConverter;
import pers.lonestar.framework.utils.support.converters.DoubleConverter;
import pers.lonestar.framework.utils.support.converters.FloatConverter;
import pers.lonestar.framework.utils.support.converters.IntegerConverter;
import pers.lonestar.framework.utils.support.converters.LongConverter;
import pers.lonestar.framework.utils.support.converters.NullConverter;
import pers.lonestar.framework.utils.support.converters.ShortConverter;
import pers.lonestar.framework.utils.support.converters.StringConverter;
import pers.lonestar.framework.utils.support.metadata.CellData;

public class ConverterUtil {
    private static final Map<Class, Converter> CONVERTER_MAP = new HashMap<>();

    static {
        ByteConverter byteConverter = new ByteConverter();
        CONVERTER_MAP.put(byte.class, byteConverter);
        CONVERTER_MAP.put(Byte.class, byteConverter);
        ShortConverter shortConverter = new ShortConverter();
        CONVERTER_MAP.put(short.class, shortConverter);
        CONVERTER_MAP.put(Short.class, shortConverter);
        IntegerConverter integerConverter = new IntegerConverter();
        CONVERTER_MAP.put(int.class, integerConverter);
        CONVERTER_MAP.put(Integer.class, integerConverter);
        LongConverter longConverter = new LongConverter();
        CONVERTER_MAP.put(long.class, longConverter);
        CONVERTER_MAP.put(Long.class, longConverter);
        FloatConverter floatConverter = new FloatConverter();
        CONVERTER_MAP.put(float.class, floatConverter);
        CONVERTER_MAP.put(Float.class, floatConverter);
        DoubleConverter doubleConverter = new DoubleConverter();
        CONVERTER_MAP.put(double.class, doubleConverter);
        CONVERTER_MAP.put(Double.class, doubleConverter);
        StringConverter stringConverter = new StringConverter();
        CONVERTER_MAP.put(String.class, stringConverter);
        BooleanConverter booleanConverter = new BooleanConverter();
        CONVERTER_MAP.put(boolean.class, booleanConverter);
        CONVERTER_MAP.put(Boolean.class, booleanConverter);
        DateConverter dateConverter = new DateConverter();
        CONVERTER_MAP.put(Date.class, dateConverter);
        CalendarConverter calendarConverter = new CalendarConverter();
        CONVERTER_MAP.put(Calendar.class, calendarConverter);
        NullConverter nullConverter = new NullConverter();
        CONVERTER_MAP.put(null, nullConverter);
    }

    public static Object convertToJavaObject(CellData cellData, Field field) {
        if (cellData.checkEmpty()) {
            return null;
        }
        Class<?> fieldType = field.getType();
        Converter converter = CONVERTER_MAP.get(fieldType);
        if (converter == null) {
            return cellData.getStringValue();
        }
        return converter.convertToJavaObject(cellData);
    }

    public static CellData convertToCellData(Object data) {
        Converter converter = getConverter(data);
        return converter.convertToCellData(data);
    }

    public static Converter getConverter(Object data) {
        if (data == null) {
            return CONVERTER_MAP.get(null);
        } else if (data instanceof Byte) {
            return CONVERTER_MAP.get(Byte.class);
        } else if (data instanceof Short) {
            return CONVERTER_MAP.get(Short.class);
        } else if (data instanceof Integer) {
            return CONVERTER_MAP.get(Integer.class);
        } else if (data instanceof Long) {
            return CONVERTER_MAP.get(Long.class);
        } else if (data instanceof Float) {
            return CONVERTER_MAP.get(Float.class);
        } else if (data instanceof Double) {
            return CONVERTER_MAP.get(Double.class);
        } else if (data instanceof String) {
            return CONVERTER_MAP.get(String.class);
        } else if (data instanceof Boolean) {
            return CONVERTER_MAP.get(Boolean.class);
        } else if (data instanceof Date) {
            return CONVERTER_MAP.get(Date.class);
        } else if (data instanceof Calendar) {
            return CONVERTER_MAP.get(Calendar.class);
        } else {
            return CONVERTER_MAP.get(String.class);
        }
    }

}
